﻿using System;
using System.Threading.Tasks;

using Windows.UI.Xaml;

using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;

using Uhimania.Libraries.Test;

using Uhimania.Libraries.Windows.Interactivity;

namespace Windows.InteractivityTest
{
    [TestClass]
    public class TriggerBaseTest
    {
        #region TriggerBase

        #region 正常ケース
        [TestMethod]
        public async Task TriggerBase_正常ケース()
        {
            await UiTestHelper.ExecuteOnUiThread(() =>
            {
                var obj = new Mock();
                var action1 = new TriggerActionMock();
                var action2 = new TriggerActionMock();
                var action3 = new TriggerActionMock();

                var mock = new TriggerBaseMock();
                mock.Actions.Add(action1);
                mock.Actions.Add(action2);
                mock.Actions.Add(action3);

                mock.Attach(obj);
                mock.AssociatedObject.Is(obj);
                mock.attach.Is(true);
                action1.AssociatedObject.Is(obj);
                action2.AssociatedObject.Is(obj);
                action3.AssociatedObject.Is(obj);

                mock.Invoke("foo");
                action1.message.Is("foo");
                action2.message.Is("foo");
                action3.message.Is("foo");

                mock.Detach();
                mock.AssociatedObject.IsNull();
                mock.detach.Is(true);
                action1.AssociatedObject.IsNull();
                action2.AssociatedObject.IsNull();
                action3.AssociatedObject.IsNull();
            });
        }
        #endregion

        #endregion

        #region TriggerBase<T>

        #region 正常ケース
        [TestMethod]
        public async Task TriggerBase_T_正常ケース()
        {
            await UiTestHelper.ExecuteOnUiThread(() =>
            {
                var obj = new Mock();
                var action1 = new TriggerActionMock();
                var action2 = new TriggerActionMock();
                var action3 = new TriggerActionMock();

                var mock = new TriggerBaseTMock();
                mock.Actions.Add(action1);
                mock.Actions.Add(action2);
                mock.Actions.Add(action3);

                mock.Attach(obj);
                mock.AssociatedObject.Is(obj);
                mock.attach.Is(true);
                action1.AssociatedObject.Is(obj);
                action2.AssociatedObject.Is(obj);
                action3.AssociatedObject.Is(obj);

                mock.Invoke("foo");
                action1.message.Is("foo");
                action2.message.Is("foo");
                action3.message.Is("foo");

                mock.Detach();
                mock.AssociatedObject.IsNull();
                mock.detach.Is(true);
                action1.AssociatedObject.IsNull();
                action2.AssociatedObject.IsNull();
                action3.AssociatedObject.IsNull();
            });
        }
        #endregion

        #endregion

        #region Mock

        private class Mock : DependencyObject
        {
        }

        private class TriggerActionMock : TriggerAction<Mock>
        {
            public string message;
            protected override void Invoke(object parameter)
            {
                this.message = parameter as string;
            }
        }

        private class TriggerBaseMock : Uhimania.Libraries.Windows.Interactivity.TriggerBase
        {
            public bool attach = false;
            protected override void OnAttached()
            {
                base.OnAttached();
                this.attach = true;
            }

            public bool detach = false;
            protected override void OnDetaching()
            {
                base.OnDetaching();
                this.detach = true;
            }

            public void Invoke(string message)
            {
                this.InvokeActions(message);
            }
        }

        private class TriggerBaseTMock : TriggerBase<Mock>
        {
            public bool attach = false;
            protected override void OnAttached()
            {
                base.OnAttached();
                this.attach = true;
            }

            public bool detach = false;
            protected override void OnDetaching()
            {
                base.OnDetaching();
                this.detach = true;
            }

            public void Invoke(string message)
            {
                this.InvokeActions(message);
            }
        }

        #endregion
    }
}
